package model;

import java.util.Date;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.workplicity.entry.Entry;
import org.workplicity.util.Helper;
import org.workplicity.worklet.WorkletContext;

import cc.test.bridge.SublineInterface;
import cc.test.bridge.TransactionInterface;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Transaction extends Entry implements TransactionInterface
{
	private static final long serialVersionUID = 1L;
	protected final String repositoryName = "Transactions";
	protected String name = "N/A";
	protected Double amount = 0.0;
	protected Date date = new Date();
	protected Integer parentLineId = -1;

	/**
	 * Default no argument constructor
	 */
	public Transaction()
	{
	}

	/**
	 * Constructor taking in the Transaction ID
	 * 
	 * @param id The integer of the transaction ID
	 */
	public Transaction(Integer id)
	{
		this.parentLineId = id;
	}

	@Override
	/**
	 * Getter for repositoryName
	 * 
	 * @return The repositoryName String
	 */
	public String getRepositoryName()
	{
		return this.repositoryName;
	}
	
	@Override
	/**
	 * Getter for name
	 * 
	 * @return The name String
	 */
	public String getName()
	{
		return this.name;
	}

	@Override
	/**
	 * Setter for name
	 * 
	 * @param The String containing the Transaction name
	 */
	public void setName(String name)
	{
		this.name = name;
		
		// If created already (it is not in the create hamper)
		if (this.id != -1)
		{
			// If TransUpdates hamper does not contain the transaction already
			if (!Hampers.getTransUpdates().containsKey(this.id))
			{
				Hampers.getTransUpdates().put(this.id, this);
			}
		}
	}

	@Override
	/**
	 * Getter for amount
	 * 
	 * @return The amount double
	 */
	public Double getAmount()
	{
		return this.amount;
	}

	@Override
	/**
	 * Setter for amount
	 * 
	 * @param The Double containing the Transaction amount
	 */
	public void setAmount(Double amount)
	{
		this.amount = amount;
		
		// If created already (it is not in the create hamper)
		if (this.id != -1)
		{
			// If TransUpdates hamper does not contain the transaction already
			if (!Hampers.getTransUpdates().containsKey(this.id))
			{
				Hampers.getTransUpdates().put(this.id, this);
			}
		}
	}
	
	@Override
	/**
	 * Getter for date
	 * 
	 * @return The date Date
	 */
	public Date getDate()
	{
		return this.date;
	}

	@Override
	/**
	 * Setter for date
	 * 
	 * @param The Date containing the Transaction date
	 */
	public void setDate(Date date)
	{
		this.date = date;
		
		// If created already (it is not in the create hamper)
		if (this.id != -1)
		{
			// If TransUpdates hamper does not contain the transaction already
			if (!Hampers.getTransUpdates().containsKey(this.id))
			{
				Hampers.getTransUpdates().put(this.id, this);
			}
		}
	}

	/**
	 * Getter for parentLineId
	 * 
	 * @return The parentLineId Integer
	 */
	public Integer getParentLineId()
	{
		return parentLineId;
	}

	/**
	 * Setter for parentLineId
	 * 
	 * @param parentLineId Integer containing the parentLineId
	 */
	public void setParentLineId(Integer parentLineId)
	{
		this.parentLineId = parentLineId;
	}

	/**
	 * Getter for serialVersionUid
	 * 
	 * @return serialVersionUID The long containing the serialVersionUID
	 */
	public static long getSerialversionuid()
	{
		return serialVersionUID;
	}

	/**
	 * Commits a newly created Transaction to the repository
	 * 
	 * @return A boolean of if the Transaction was successfully committed.
	 */
	public static Boolean commitTransactionCreates()
	{
		Boolean successful = true;
		
		for (TransactionInterface transaction : Hampers.getTransCreates()
				.values())
		{
			// insert line into Mongo
			try
			{
				successful = Helper.insert((Transaction) transaction,
						"Transactions", WorkletContext.getInstance());
				
				System.out.println("Created transaction with id: "
						+ transaction.getId());
			}
			catch (Exception e)
			{
				System.out
						.println("Error: Could not create transaction with id "
								+ transaction.getId());
				
				e.printStackTrace();
				successful = false;
			}
			
			// Give new Id to parent Subline
			if (Hampers.getSublineUpdates().containsKey(
					((Transaction) transaction).getParentLineId()))
			{
				SublineInterface subline = Hampers.getSublineUpdates().get(
						((Transaction) transaction).getParentLineId());
				
				if (!((Subline) subline).getTransactionIds().contains(
						transaction.getId()))
				{
					((Subline) subline).transactionIds.add(transaction.getId());
				}
			}
			else if (Hampers.getSublineCreates().containsKey(
					((Transaction) transaction).getParentLineId()))
			{
				SublineInterface subline = Hampers.getSublineCreates().get(
						((Transaction) transaction).getParentLineId());
				
				if (!((Subline) subline).getTransactionIds().contains(
						transaction.getId()))
				{
					((Subline) subline).transactionIds.add(transaction.getId());
				}
			}
		}
		
		return successful;
	}

	/**
	 * Commits an updated Transaction to the repository
	 * 
	 * @return A boolean of if the Transaction was successfully committed.
	 */
	public static Boolean commitTransactionUpdates()
	{
		Boolean successful = true;
		
		for (TransactionInterface transaction : Hampers.getTransUpdates()
				.values())
		{
			// update transaction in Mongo
			try
			{
				successful = Helper.insert((Transaction) transaction,
						"Transactions", WorkletContext.getInstance());
				
				System.out.println("Updated transaction with id "
						+ transaction.getId());
			}
			catch (Exception e)
			{
				System.out
						.println("Error: Could not update transaction with id "
								+ transaction.getId());
				
				e.printStackTrace();
				successful = false;
			}
		}
		
		return successful;
	}

	/**
	 * Deletes a Transaction from the repository
	 * 
	 * @return A boolean of if the Transaction was successfully deleted.
	 */
	public static Boolean commitTransactionDeletes(Transaction transaction)
	{
		// delete transaction in Mongo
		Boolean successful = true;
		
		try
		{
			successful = Helper.delete((Transaction) transaction,
					"Transactions", WorkletContext.getInstance());
			
			System.out.println("Deleted transaction with id "
					+ transaction.getId());
		}
		catch (Exception e)
		{
			System.out.println("Error: Could not delete transaction with id "
					+ transaction.getId());
			
			e.printStackTrace();
			successful = false;
		}
		
		if (successful)
		{
			if (Hampers.getSublineUpdates().containsKey(
					transaction.getParentLineId()))
			{
				SublineInterface subline = Hampers.getSublineUpdates().get(
						transaction.getParentLineId());
				((Subline) subline).getTransactionIds().remove(transaction.id);
			}
			else if (Hampers.getSublineCreates().containsKey(
					transaction.getParentLineId()))
			{
				SublineInterface subline = Hampers.getSublineCreates().get(
						transaction.getParentLineId());
				((Subline) subline).getTransactionIds().remove(transaction.id);
			}
		}
		
		return successful;
	}
	
	@Override
	/**
	 * Dummy commit function for TransactionInterface 
	 */
	public Boolean commit()
	{
		return null;
	}
}
